﻿
Public Class resolver
    Private creator As Dictionary(Of Type, _do(Of Object)) = Nothing

    Public Function size() As Int32
        Return creator.Count()
    End Function

    Public Sub register(ByVal T As Type, ByVal d As _do(Of Object))
        assert(Not d Is Nothing)
        creator(T) = d
    End Sub

    Public Sub register(Of T)(ByVal d As _do(Of T))
        assert(Not d Is Nothing)
        register(GetType(T), Function() As Object
                                 Dim rtn As Object = Nothing
                                 rtn = d()
                                 If rtn Is Nothing Then
                                     assert(False,
                                            "failed to resolve " + GetType(T).FullName + " via " + invokeMethodName(d))
                                 End If
                                 Return rtn
                             End Function)
    End Sub

    Public Function resolve(ByVal T As Type) As Object
        Dim create As _do(Of Object) = Nothing
        create = resolver(T)
        If create Is Nothing Then
            Return Nothing
        Else
            Dim rtn As Object = Nothing
            rtn = create()
            If rtn Is Nothing Then
                assert(False,
                       "failed to resolve " + T.FullName + " via " + invokeMethodName(create))
            End If
            Return rtn
        End If
    End Function

    Public Function resolve(Of T)() As T
        Return convertor.cast(Of T)(resolve(GetType(T)))
    End Function

    Public Function hasResolver(ByVal T As Type) As Boolean
        Return creator.ContainsKey(T)
    End Function

    Public Function hasResolver(Of T)() As Boolean
        Return hasResolver(GetType(T))
    End Function

    Public Function resolver(ByVal T As Type) As _do(Of Object)
        If hasResolver(T) Then
            Return creator(T)
        Else
            Return Nothing
        End If
    End Function

    Public Function resolver(Of T)() As _do(Of Object)
        Return resolver(GetType(T))
    End Function

    Public Function [erase](ByVal T As Type) As Boolean
        Return creator.Remove(T)
    End Function

    Public Function [erase](Of T)() As Boolean
        Return [erase](GetType(T))
    End Function

    Public Sub New()
        creator = New Dictionary(Of Type, _do(Of Object))()
    End Sub
End Class
